/*
 * This file is part of syncfw-example package
 *
 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to 
 * deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,     
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS  
 * IN THE SOFTWARE. 
 */

#include "eventsexample.h"
#include <libsyncpluginmgr/PluginCbInterface.h>
#include <LogMacros.h>
#include <QTimer>
#include <QDateTime>
#include <QMap>
#include <QUrl>
#include <meventfeed.h>
#include <gq/GConfItem>
#include <QVariant>

extern "C" EventsExample* createPlugin(const QString& aPluginName,
                                       const Buteo::SyncProfile& aProfile,
                                       Buteo::PluginCbInterface *aCbInterface)
{
    return new EventsExample(aPluginName, aProfile, aCbInterface);
}

extern "C" void destroyPlugin(EventsExample*aClient)
{
    delete aClient;
}

EventsExample::EventsExample(const QString& aPluginName,
                             const Buteo::SyncProfile& aProfile,
                             Buteo::PluginCbInterface *aCbInterface) :
    ClientPlugin(aPluginName, aProfile, aCbInterface)
{
    FUNCTION_CALL_TRACE;
}

EventsExample::~EventsExample()
{
    FUNCTION_CALL_TRACE;
}

bool EventsExample::init()
{
    FUNCTION_CALL_TRACE;

    //The sync profiles can have some specific key/value pairs this info
    //can be accessed by this method.
    iProperties = iProfile.allNonStorageKeys();

    //return false - if error
    //syncfw will call this method first if the plugin is able to initialize properly
    //and its ready for sync it should return 'true' in case of any error return false.
    return true;
}

bool EventsExample::uninit()
{
    FUNCTION_CALL_TRACE;

    // called before unloading the plugin , the plugin should clean up
    return true;
}

bool EventsExample::startSync()
{
    FUNCTION_CALL_TRACE;

    // This method is called after init(), the plugin is expected to return
    // either true or false based on if the sync was started successfully or
    // it failed for some reason
    //call appropriate slots based on the status of operation success/failed...
    //updateFeed Its just a helper function.

    GConfItem enabledConfItem("/apps/ControlPanel/SyncFWExample/EnableFeed");
    QVariant enabledVariant = enabledConfItem.value();
    if (enabledVariant.isValid()) {
        bool enabled = enabledVariant.toBool();
        if (!enabled) {
            MEventFeed::instance()->removeItemsBySourceName("SyncFW-example");
            return false;
        }
    } else {
        enabledConfItem.set(true);
    }

    QTimer::singleShot(1, this, SLOT(updateFeed()));

    return true;
}

void EventsExample::abortSync(Sync::SyncStatus aStatus)
{
    FUNCTION_CALL_TRACE;
    Q_UNUSED(aStatus);
    // This method is called if used cancels the
    // sync in between , with the applet use case
    // it should not ideally happen as there is no UI
    // in case of device sync and accounts sync we have
    // a cancel button
}

bool EventsExample::cleanUp()
{
    FUNCTION_CALL_TRACE;

    // this method is called in case of account being deleted
    // or the profile being deleted from UI in case of applet
    // it will not be called ....need to check as if there
    // can be any use case for this
    return true;
}

Buteo::SyncResults EventsExample::getSyncResults() const
{
    FUNCTION_CALL_TRACE;
    return iResults;
}

void EventsExample::connectivityStateChanged(Sync::ConnectivityType aType,
                                             bool aState)
{
    FUNCTION_CALL_TRACE;
    // This function notifies of the plugin of any connectivity related state changes
    LOG_DEBUG("Received connectivity change event:" << aType << " changed to " << aState);
    if ((aType == Sync::CONNECTIVITY_INTERNET) && (aState == false)) {
        // Network disconnect!!
    }
}

void EventsExample::syncSuccess()
{
    FUNCTION_CALL_TRACE;
    updateResults(Buteo::SyncResults(QDateTime::currentDateTime(), Buteo::SyncResults::SYNC_RESULT_SUCCESS, Buteo::SyncResults::NO_ERROR));
    //Notify Sync FW of result - Now sync fw will call uninit and then will unload plugin
    emit success(getProfileName(), "Success!!");
}

void EventsExample::syncFailed()
{
    FUNCTION_CALL_TRACE;
    //Notify Sync FW of result - Now sync fw will call uninit and then will unload plugin
    updateResults(Buteo::SyncResults(QDateTime::currentDateTime(),
                                     Buteo::SyncResults::SYNC_RESULT_FAILED, Buteo::SyncResults::ABORTED));
    emit error(getProfileName(), "Error!!", Buteo::SyncResults::SYNC_RESULT_FAILED);
}

void EventsExample::updateResults(const Buteo::SyncResults &aResults)
{
    FUNCTION_CALL_TRACE;
    iResults = aResults;
    iResults.setScheduled(true);
}

void EventsExample::updateFeed()
{
    FUNCTION_CALL_TRACE;

    bool success = false;
    //Ok assuming that we now have the data that needs to be updated to event feed
    qlonglong id  = MEventFeed::instance()->addItem(QString("icon-m-transfer-sync"),
                                                    QString("SyncFW Example"),
                                                    QString("Event Feed updated"),
                                                    QStringList(),
                                                    QDateTime::currentDateTime(),
                                                    QString(),
                                                    false,
                                                    QUrl(),
                                                    QString("SyncFW-example"),
                                                    QString("SyncFW and event feed example app"));
    if (id != -1) {
        success = true;
    }
    if(success)
        syncSuccess();
    else
        syncFailed();
}
